﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Web;
using System.Web.Caching;

namespace Core
{
    public class GlobalUtility
    {
        private static readonly byte[] IV = new byte[] { 240, 3, 45, 29, 0, 76, 173, 59 };

        /// <summary>
        /// Gets the db connection string.
        /// </summary>
        public static string KcDbConnectionString
        {
            get
            {
                string connStr = ConfigurationManager.ConnectionStrings["WebsiteDBConnectionString"].ConnectionString;
                return connStr;
            }
        }

        /// <summary>
        /// Gets the umbraco db connection string.
        /// </summary>
        public static string UmbracoDbConnectionString
        {
            get
            {
                try
                {
                    string dbEncryptKey = ConfigurationManager.AppSettings["DbEncryptKey"];
                    string connectionString;

                    if (ConfigurationManager.AppSettings["DbConnectionString"] != null)
                    {          
                        //Use Web.DynamicConfiguration library
                        connectionString = ConfigurationManager.AppSettings["umbracoDbDSN"];
                    }
                    else
                    {
                        connectionString = GetUmbracoConnectionString();
                    }

                    if (string.IsNullOrEmpty(dbEncryptKey))
                    {
                        return connectionString;
                    }
                    return KimberlyClark.EuroCRM.Encryption.Decrypt(connectionString, dbEncryptKey);
                }
                catch
                {
                    throw new Exception("Connection string decryption failed. Please check your encryption key.");
                }
            }
        }

        public static string DbEncryptKey
        {
            get
            {
                try
                {
                    return ConfigurationManager.AppSettings["DbEncryptKey"];
                }
                catch
                {
                    return String.Empty;
                }
            }
        }

        /// <summary>
        /// Gets the current URL.
        /// </summary>
        /// <returns></returns>
        private static string GetCurrentUrl()
        {
            try
            {
                const string key = "kcCurrentUrlPath";
                var kcCurrentUrlPath = HttpContext.Current.Cache[key];
                string urlPath;
                if (kcCurrentUrlPath == null)
                {
                    urlPath = HttpContext.Current.Request.Url.AbsoluteUri.ToLower();
                    //CacheDependency dep = new CacheDependency(System.Web.HttpContext.Current.Server.MapPath("~/config/AppSetting.config"), DateTime.Now);
                    HttpContext.Current.Cache.Insert(key, urlPath, null, DateTime.Now.AddHours(1), Cache.NoSlidingExpiration);
                }
                else
                    urlPath = kcCurrentUrlPath.ToString();

                return urlPath;
            }
            catch
            {
                return "";
            }
        }

        /// <summary>
        /// Gets the connection string.
        /// </summary>
        /// <returns></returns>
        public static string GetKcConnectionString()
        {
            //string urlPath = GetCurrentUrl();
            //string connStr;
            //if (ValidateURL(urlPath, ConfigurationManager.AppSettings["urlLocal"]))
            //    connStr = ConfigurationManager.ConnectionStrings["kcLocal"];
            //else if (ValidateURL(urlPath, ConfigurationManager.AppSettings["urlDev"]))
            //    connStr = ConfigurationManager.AppSettings["kcDev"];
            //else if (ValidateURL(urlPath, ConfigurationManager.AppSettings["urlQA"]))
            //    connStr = ConfigurationManager.AppSettings["kcQA"];
            //else if (ValidateURL(urlPath, ConfigurationManager.AppSettings["urlProd"]))
            //    connStr = ConfigurationManager.AppSettings["kcProd"];
            //else
            //    connStr = ConfigurationManager.AppSettings["kcProd"];

            string connStr = ConfigurationManager.ConnectionStrings["WebsiteDBConnectionString"].ConnectionString;
            return connStr;
        }

        /// <summary>
        /// Gets the umbraco connection string.
        /// </summary>
        /// <returns></returns>
        public static string GetUmbracoConnectionString()
        {
            string urlPath = GetCurrentUrl();
            string connStr;
            if (ValidateURL(urlPath, ConfigurationManager.AppSettings["urlLocal"]))
                connStr = ConfigurationManager.AppSettings["kcUmbracoLocal"];
            else if (ValidateURL(urlPath, ConfigurationManager.AppSettings["urlDev"]))
                connStr = ConfigurationManager.AppSettings["kcUmbracoDev"];
            else if (ValidateURL(urlPath, ConfigurationManager.AppSettings["urlQA"]))
                connStr = ConfigurationManager.AppSettings["kcUmbracoQA"];
            else if (ValidateURL(urlPath, ConfigurationManager.AppSettings["urlProd"]))
                connStr = ConfigurationManager.AppSettings["kcUmbracoProd"];
            else
                connStr = ConfigurationManager.AppSettings["kcUmbracoProd"];
            return connStr;
        }

        /// <summary>
        /// Gets the name of the umbraco URL app setting.
        /// </summary>
        /// <returns></returns>
        public static string GetUmbracoUrlAppSettingName()
        {
            string urlPath = GetCurrentUrl();
            string appSettingName;
            if (ValidateURL(urlPath, ConfigurationManager.AppSettings["urlLocal"]))
                appSettingName = "kcUmbracoLocal";
            else if (ValidateURL(urlPath, ConfigurationManager.AppSettings["urlDev"]))
                appSettingName = "kcUmbracoDev";
            else if (ValidateURL(urlPath, ConfigurationManager.AppSettings["urlQA"]))
                appSettingName = "kcUmbracoQA";
            else if (ValidateURL(urlPath, ConfigurationManager.AppSettings["urlProd"]))
                appSettingName = "kcUmbracoProd";
            else
                appSettingName = "kcUmbracoProd";
            return appSettingName;
        }

        /// <summary>
        /// Gets the name of the kc URL app setting.
        /// </summary>
        /// <returns></returns>
        public static string GetKcUrlAppSettingName()
        {
            string urlPath = GetCurrentUrl();
            string appSettingName;
            if (ValidateURL(urlPath, ConfigurationManager.AppSettings["urlLocal"]))
                appSettingName = "kcLocal";
            else if (ValidateURL(urlPath, ConfigurationManager.AppSettings["urlDev"]))
                appSettingName = "kcDev";
            else if (ValidateURL(urlPath, ConfigurationManager.AppSettings["urlQA"]))
                appSettingName = "kcQA";
            else if (ValidateURL(urlPath, ConfigurationManager.AppSettings["urlProd"]))
                appSettingName = "kcProd";
            else
                appSettingName = "kcProd";
            return appSettingName;
        }

        /// <summary>
        /// Validates the URL.
        /// </summary>
        /// <param name="url">The URL.</param>
        /// <param name="text">The text.</param>
        /// <returns></returns>
        private static bool ValidateURL(string url, string text)
        {
            List<string> names = new List<string>(text.Split(';'));

            return names.Any(name => url.Contains(name.Trim().ToLower()));
        }

        /// <summary>
        /// Sorts the direction.
        /// </summary>
        /// <param name="column">The column.</param>
        /// <returns></returns>
        public static string SortDirection(String column)
        {

            // By default, set the sort direction to ascending.
            string sortDirection = "ASC";

            // Retrieve the last column that was sorted.
            string sortExpression = HttpContext.Current.Session["SortExpression"] as string;

            if (sortExpression != null)
            {
                // Check if the same column is being sorted.
                // Otherwise, the default value can be returned.
                if (sortExpression == column)
                {
                    string lastDirection = HttpContext.Current.Session["SortDirection"] as string;
                    if ((lastDirection != null) && (lastDirection == "ASC"))
                    {
                        sortDirection = "DESC";
                    }
                }
            }
            // Save new values in ViewState.
            HttpContext.Current.Session["SortDirection"] = sortDirection;
            HttpContext.Current.Session["SortExpression"] = column;

            return sortDirection;
        }

        /// <summary>
        /// Encrypts the specified s.
        /// </summary>
        /// <param name="s">The s.</param>
        /// <param name="key">The key.</param>
        /// <returns></returns>
        public static string Encrypt(string s, string key)
        {

            if (string.IsNullOrEmpty(s)) return string.Empty;

            byte[] buffer = Encoding.ASCII.GetBytes(s);

            TripleDESCryptoServiceProvider des =
                new TripleDESCryptoServiceProvider();

            MD5CryptoServiceProvider MD5 =
                new MD5CryptoServiceProvider();

            des.Key =
                MD5.ComputeHash(Encoding.ASCII.GetBytes(key));

            des.IV = IV;
            string result = Convert.ToBase64String(
                des.CreateEncryptor().TransformFinalBlock(
                    buffer, 0, buffer.Length));

            return result;
        }

        /// <summary>
        /// Decrypts the specified s.
        /// </summary>
        /// <param name="s">The s.</param>
        /// <param name="key">The key.</param>
        /// <returns></returns>
        public static string Decrypt(string s, string key)
        {
            if (string.IsNullOrEmpty(s)) return string.Empty;

            string result;

            try
            {
                byte[] buffer = Convert.FromBase64String(s);

                TripleDESCryptoServiceProvider des =
                    new TripleDESCryptoServiceProvider();

                MD5CryptoServiceProvider MD5 =
                    new MD5CryptoServiceProvider();

                des.Key =
                    MD5.ComputeHash(Encoding.ASCII.GetBytes(key));

                des.IV = IV;

                result = Encoding.ASCII.GetString(
                    des.CreateDecryptor().TransformFinalBlock(
                    buffer, 0, buffer.Length));
            }
            catch
            {
                return "";
            }

            return result;
        }

        /// <summary>
        /// Logs the exception.
        /// </summary>
        /// <param name="ex">The ex.</param>
        public static void LogException(Exception ex)
        {
            Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
        }

        private static string _currentCultureInfoCode;

        /// <summary>
        /// Gets a value indicating whether this instance is local language mode.
        /// </summary>
        /// <value>
        /// 	<c>true</c> if this instance is local language mode; otherwise, <c>false</c>.
        /// </value>
        public static bool IsLocalLanguageMode
        {
            get
            {
                try
                {
                    string curCulture = CookieManager.GetCookie("lang", "culture");
                    if (string.IsNullOrEmpty(curCulture))
                    {
                        _currentCultureInfoCode = "en-US";
                        return false;
                    }
                    if (curCulture != "en-US")
                    {
                        // local
                        _currentCultureInfoCode = curCulture;
                        return true;
                    }
                    _currentCultureInfoCode = "en-US";
                    return false;
                }
                catch
                {
                    _currentCultureInfoCode = "en-US";
                    return false;
                }
            }
        }

        /// <summary>
        /// Gets the current culture info.
        /// </summary>
        public static string CurrentCultureInfo
        {
            get
            {
                try
                {
                    if (IsLocalLanguageMode)
                    {
                        return "en-US";
                    }
                    return _currentCultureInfoCode;
                }
                catch
                {
                    return "en-US";
                }
            }
        }
    }
}
